﻿using System.Collections.Generic;

namespace Framework
{
    public class MacroCommand : Command
    {
        protected List<Command[]> _listCommand = new List<Command[]>();
        protected int _currentIndex;
        protected int _semaphore;

        public MacroCommand()
        {
            
        }

        public void AddComand(Command command)
        {
            _listCommand.Add(new[] {command});
        }

        public void AddParallelCommands(Command[] commands)
        {
            _listCommand.Add(commands);
        }

        protected override void StartCommand()
        {
            _currentIndex = 0;
            StartNextCommand();
        }

        protected override void StopCommand()
        {
            Command[] commands = _listCommand[_currentIndex];
            for (int i = commands.Length - 1; i >= 0; --i)
            {
                Command command = commands[i];
                if (command.status == Status.Runing)
                {
                    command.completedEvent -= OnChildCommandCompleted;
                    command.Stop();                    
                }
            }
        }

        protected void StartNextCommand()
        {
            Command[] commands = _listCommand[_currentIndex];
            _semaphore = commands.Length;
            for (int i = _semaphore - 1; i >= 0; --i)
            {
                Command command = commands[i];
                command.completedEvent += OnChildCommandCompleted;
                command.Start(_context);
            }
        }

        protected void OnChildCommandCompleted(Command command)
        {
            command.completedEvent -= OnChildCommandCompleted;
            --_semaphore;
            if (_semaphore <= 0)
            {
                Command[] commands = _listCommand[_currentIndex];
                Status status = Status.Success;
                for (int i = commands.Length - 1; i >= 0; --i)
                {
                    Command childCommand = commands[i];
                    if (childCommand.status == Status.Fail)
                    {
                        status = Status.Fail;
                        break;
                    }
                }
                
                if (status == Status.Fail)
                {
                    OnCompleted(status);
                }
                else
                {
                    ++_currentIndex;
                    if (_currentIndex < _listCommand.Count)
                    {
                        StartNextCommand();
                    }
                    else
                    {
                        OnCompleted(Status.Success);
                    }
                }
                
            }
        }
    }
}